home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-01-01 | 23.3 KB | 1,033 lines |
-
-
-
-
- A complete dissection of Gfx-Zone
-
- by XmikeX
-
-
- [Note from Jeff:] some of this
- listing may not print properly in the
- 6-column mode.
-
- The following is a disassembly of
- the ML code itself. Although I won't
- go through it 100% step by step,
- important points shall be perused for
- the purposes of clarification, and to
- be honest, for a little self-
- introspection on my part.
-
- The program starts out quite simply
- with the start address and a
- labelling of important memory
- locations (generally used as pointers
- throughout the program).
-
- ;--------------------------------
- *= $c000; start of program
- ;--------------------------------
- point = $fb ; LSB = point ($fb)
- ; MSB = point+1 ($fc)
- temp = $cfff ; MSB byte storage
- temp2 = $cffe ; used by FLD routine
- temp3 = $cffd ; $cffa/cffb for
- ; TBB/AMJ player uses these.
- looper = $ccfc ; see pause routine
- hit = $ccf9 ; see pause routine
- ;----------------------------------
-
- init lda #$36 ; #$36 is our
- ;kill-basic value, so
- sta $01 ; store the kill-basic value
- into $01 and move the
- ; basic rom out of the way,
- exposing the ram underneath.
-
- [AssEd. Note : For general
- edification, location $01 works as
- follows in C64]
- [ - bit 0: ROM/RAM at $a000 1=Basic
- 0=RAM]
- [ - bit 1: ROM/RAM at $e000 1=Kernal
- 0=RAM]
- [ - bit 2: ROM or I/O block 1=I/O
- 0=ROM]
- [ - bits 3,4,5 are cassette
- related........]
- [ - bits 6 & 7 are not connected in
- the C64]
- [ - bit 6 checks the status of the
- caps lock (ascii/cc) key on C128.]
-
- lda #$00 ; ok...set up accumulator
- as #$00
- sta $d020; change screen and
- sta $d021; border to black (i.e.,
- #$00)
- sta point; store LSB of pointer
- (which is now #$00)
- lda #$00 ; initialize the looper
- sta looper
-
- Ok... So what is going on here?
- Basically, we are telling Basic to
- take a hike so that we can use the
- memory it once inhabited. We are also
- setting up the LEAST SIGNIFICANT BYTE
- pointer for the indirect Y function.
- This is a powerful tool in 6502
- assembly and we will get to it later
- :). The "looper" is just a memory
- location that the program will use in
- its "pause" subroutine. Right now, it
- is set at zero (#$00).
-
-
- UGLY lda #$fa ; try and tell
- tbb/amj music player
-
- sta $105b; what scanline to play
- at
-
- amjtune jsr $1000; jsr call to
- sys4096/amj's TBB player at $1000
-
-
- This part is really UGLY.
- Basically, I tried to extract the
- music player and tried to incorporate
- it here, but I failed for some
- unknown reason. I decided that since
- it was proving to be uncooperative
- that I should just call it from here
- and let it go off on its own. This
- presented two problems for me later.
- The first was that the music was
- playing at raster lines that were
- outside the border area. In layman's
- terms this means that it would play
- in the middle of the screen and a
- slight flicker could be seen as the
- main code flipped through the pics. I
- rectified the situation by finding
- out where it was polling its raster
- info ($105b) and sticking an #$fa in
- there. #$fa is raster line 250, which
- should correspond to the lower border
- on the screen. Yes, I could have
- modified the player code itself, but
- I was getting a bit paranoid at this
- juncture and decided not to modify
- it. The second problem is that by
- giving up control to the player
- subroutine, I lost control of timing,
- an annoyance that which we shall
- discuss later. Anyways, as you can
- see I call the player in the
- 'amjtune' subroutine and let it do
- its thing, but even though it is not
- in the main code, I've included the
- player here for the benefit of the
- reader. As this code is from someone
- else, I cannot assure a 100% correct
- disassembly, but read on..
-
-
- TBB player from SYS4096 tune by
- AMJ starts at $1000 and proceeds as
- follows: (By the way, TBB is AMJ's
- brother...trivia mode over).
-
- <start of player code>
-
- > sei ; disables interrupts
- > lda #$01
- > sta $d01a ; set up for scan line
- > lda #$7f
- > sta $dc0d ; enable timer interpts
- > lda #$35 ; lets play with roms
- > sta $01
- > lda #$00
- > ldx #$00
- > ldy #$00
- > jsr $1100 ; jsr to musix init ?
- > lda #$37 ; let's play with roms
- > sta $01
- > lda #<irq ; LSB of irq
- > sta $0314 ; stash it
- > lda #>irq
- > sta $0315 ; MSB of irq
- > lda #$3a
- > sta $d012
- > lda #$1b ; normalize the screen i
- think
- > sta $d011
- > cli ; re-enables interrupts
- > rts ; it used to jmp back to
- itself, infinite loop
- > ; as its irq routine played in the
- backgroud
-
- >irq lda #$01 ; the irq routine
- > sta $d019
- > lda #$35 ; let's play with roms
- again
- > sta $01
- > dec $d020
- > jsr $1103 ; $1103 (!) I think this
- jsr's to musix data
- > inc $d020
- > lda #$37 ; let's play with roms
- yet again
- > sta $01
- > inc selfmod+1 ; self-modifying
- code!!!
- >selfmod lda #$xx ; #$xx = this is
- the byte changed by 'inc selfmod+1'
- > and #$01
- > tax
- > lda #$105b,x ; goes to the scan
- line table ?
- > sta $d012 ; sets up the scan line
- for irq to occur
- > jmp $ea31 ; go to normal c= irq
- return
-
- <end of player code>
-
- From $105c to $10a0 or so beyond
- this there is some program data of
- unknown function. At around $1100
- there is an embedded message by the
- authors and then the music data
- follows, ending somewhere around
- $26b0 if I recall correctly. Please
- note that this tune is double-speed
- (i.e., plays twice per frame).
-
- <back to main program code>
-
- The initialization steps have
- executed and the music player has
- been told to start playing. What is
- left now is to present the C/G
- pictures to the viewer in a
- meaningful way.
-
- The main1 routine that follows
- conducts the sequence of the C/G
- displays. Its responsibility is to
- load and store the MOST SIGNIFICANT
- BYTE of the address (location) of
- each starting pic for a given pattern
- of displays and then branch out to
- the pattern subroutines, which
- display c/g pics sequentially given a
- predetermined sequence. Again, the
- MSB as with the LSB we encountered
- earlier deals with the indirect Y
- function that we shall explore
- later.
-
- main1 lda #$30 ; starting pic MSB
- sta temp ; store MSB in temp
- jsr pattern
-
- lda #$30 ; starting pic MSB
- sta temp ; store MSB in temp
- jsr pattern0
-
- lda #$c0 ; this MSB is being stored
- but pattern1 does not use it
- sta temp
- jsr pattern2
- jsr pattern1; fld bounce of the
- first intro pic only
- ; located at $3000-$37e7
- ; fld effect is quite annoying, so
- its done only once
- lda #$38
- sta temp
- jsr p0 ; p0 routine is a part
- (subset) of pattern0 routine
-
- lda #$c0 ; the rest of these are
- more of the same... calls to
- sta temp ; pattern subroutines
- jsr pattern2
-
- lda #$38
- sta temp
- jsr pattern0
-
- lda #$c0
- sta temp
- jsr pattern2
-
- lda #$30
- sta temp
- jsr pattern0
-
- lda #$c0
- sta temp
- jsr pattern2
-
- lda #$30
- sta temp
- jsr pattern0
-
- lda #$c0
- sta temp
- jsr pattern2
-
- lda #$38
- sta temp
- jsr p0
-
- lda #$c0
- sta temp
- jsr pattern2
-
- lda #$38
- sta temp
- jsr p0
-
- lda #$c0
- sta temp
- jsr pattern2
-
- jsr pattern3; last pattern before
- music loops back on itself
-
- jmp main1
-
- By now, music has looped...time to
- slow down again with the original
- pattern at the start of main1 routine
- (i.e., pattern routine that follows
- is called at the start of main1)
-
-
- "pattern" is the first of the
- pattern subroutines. Its
- responsibility is to take care of the
- first and second intro pics at the
- start of the program. It pulls the
- MSB from the temp memory location
- (the first intro pic), jsrs to the
- viewpic routine, and loads a "hit"
- value which the "pause" routine
- will then compare with an "looper"
- value. This determines how long the
- first intro pic will be shown. After
- which, "pattern" will change the MSB
- value (without affecting the MSB in
- temp) to point to the second intro
- pic, and then it repeats this process
- until the music tempo increases, upon
- which time "pattern" gives up control
- to another "patternX" subroutine.
-
- I mentioned earlier that I lost
- control of timing when I gave up some
- control to the music player code.
- That is to say, because I could not
- (at the time) incorporate the player
- code in here, I had no way of
- properly synching the pictures to the
- beat of the music as it played. I
- corrected this deficiency in true
- 'newbie' fashion. I used delay loops
- to form the core basis of what I
- could approximate as being a "beat"
- of music. The "pattern" subroutines
- use the "pause" subroutine (which
- includes the core delay loops along
- with "hit" and "looper" comparison)
- in order to determine how long a C/G
- pic should be displayed as the music
- plays in the background. I had to
- manually figure out how long it would
- take to go from its initial slow
- tempo to a faster tempo and then
- calibrate the "pattern" routine to
- give up control at the transition.
-
-
- pattern lda temp ; this sets up
- the initial -slow- flipping pattern
- of the
-
- jsr viewpic ; pics to match the -
- slow- tempo start to the AMJ tune
- lda #$11
- sta hit
- jsr pause
- lda #$08
- jsr viewpic
- lda #$11
- sta hit
- jsr pause
- lda temp
- jsr viewpic
- lda #$11
- sta hit
- jsr pause
- lda #$08
- jsr viewpic
- lda #$11
- sta hit
- jsr pause
- rts
-
-
- The other "patternX" routines and
- their subsets (p0, p10, etc.)
- basically perform addition or
- subtraction operations on the MSB
- they initially pull from the temp
- location. By doing so, you can
- display a number of different
- pictures in sequence with a minimum
- of effort. Recall that the pics are
- saved into memory initially with some
- organization behind it. That pre-
- planning combined with addition (adc)
- or subtraction (sbc) operations
- allowed me to display pictures in the
- order I desired. For example, assume
- that picture 1 is entitled "Boy",
- picture 2 is entitled "meets", and
- picture 3 is entitled "Girl". "Boy"
- is at $3000, "meets" is at $3800, and
- "Girl" is at $4000. The MSB
- represents the first 2 digits of the
- hex addresses I have just given, so
- "Boy" MSB is $30, "meets" is $38, and
- "Girl" is $40. Notice that each of
- these MSB's is precisely #$08 hex
- numbers apart! Since we haven't gone
- into the indirect Y function yet this
- may be a little premature, but it is
- logical to assume that if we had an
- indexing system in place all we would
- have to do in order to move from
- picture to picture would be to either
- add or subtract #$08! So basically
- our pictures are 8 units apart, for
- simplification as follows:
-
- lda 30 : Our house is at 30 main
- street :)
-
- jsr viewpic : Ask a photographer to
- photograph and display our house
-
- adc 8 : Inform the photographer
- that the next house is 8 blocks down
-
- jsr viewpic : Ask the photographer
- to photograph and display -that-
- house
-
- In actual code, if I wanted the
- pictures to come out sequentially as
- Boy meets Girl (remember the
- addresses we specified above) it
- would be
-
- lda #$30 : tell viewpic that "Boy"
- is at $3000 (#$30 = MSB = first two
- : digits of the hex number).
-
- jsr viewpic : display "Boy"
-
- clc ; CLC - Clears the Carry Flag..
- required step before addition
-
- adc #$08 : add another #$08 to the
- "Boy" address..#$30 + 08 = #$38
- : in other words, the address for
- "meets" which is $3800.
-
- jsr viewpic : display "meets"
- clc : required
- adc #$08 : add another #$08 to the
- "meets" address..#$38 + 08 = #$40
- : in other words, the address for
- "Girl" which is $4000.
- : REMEMBER, we are adding in
- HEXADECIMAL...
- jsr viewpic : display "Girl"
-
- Running this routine (and for
- now, don't worry about how viewpic
- works) within this program would
- allow us to display "Boy meets Girl".
- Simple, eh? The basic concepts hold
- for patternX routines that use
- subtraction except that instead of
- CLC, you are required to do a SEC
- before a subtraction operation.
-
- You will notice that the patternX
- routines jsr to the delay loop (e.g.,
- loop1) routines more directly than
- the "pattern" routines. This is
- because "pattern" required a much
- longer delay and this is why "hit"
- and "looper" were created.
-
- pattern0 lda temp
- jsr viewpic
- jsr loop1
-
- lda #$08 ; Load oddball MSB
- jsr viewpic
- jsr loop1
-
- p0 lda temp ; Load MSB from temp
- clc
- adc #$08 ; Add #$08 to it
- sta temp ; Store MSB in temp
- jsr viewpic
- jsr loop1
- lda temp ; Bring back MSB
- cmp #$b8 ; Is the MSB at the
- bne p0 ; final pic? $b800
- rts
-
- pattern1 lda #$30
- jsr viewpic
- jsr fldmain
- jsr loop2
- rts
-
- pattern2 lda #$c8 ; Load 2nd oddball
- MSB
- jsr viewpic
- jsr loop1
-
- p10 lda temp
- sec
- sbc #$08
- sta temp
- cmp #$30
- beq p10
- jsr viewpic
- jsr loop1
- lda temp
- cmp #$28
- bne p10
- rts
-
- pattern3 lda #$c8
- jsr viewpic
- jsr loop1
- lda #$78
- jsr viewpic
- jsr loop1
- lda #$a0
- jsr viewpic
- jsr loop1
- lda #$40
- jsr viewpic
- jsr loop1
- lda #$38
- jsr viewpic
- jsr loop1
- lda #$30
- jsr viewpic
- jsr loop1
- lda #$08
- jsr viewpic
- jsr loop1
- lda #$60
- jsr viewpic
- jsr loop1
- lda #$a8
- jsr viewpic
- jsr loop1
- lda #$68
- jsr viewpic
- jsr loop1
- lda #$70
- jsr viewpic
- jsr loop1
- lda #$80
- jsr viewpic
- jsr loop1
- lda #$90
- jsr viewpic
- jsr loop1
- lda #$88
- jsr viewpic
- jsr loop1
- jsr loop1
- jsr loop1
- jsr loop1
- jsr loop1
- ldx #$30
- jsr d1
- rts
-
-
- Ah, here we have reached the
- famous "viewpic". You will notice it
- doesn't do much. In fact, all it
- does is store the MSB pointer for the
- indirect Y function and "passes the
- buck" so to speak to the display
- routine. :)
-
- viewpic sta point+1; Store MSB
- pointer
- jsr display
- rts
-
-
- WARNING : INELEGANT timing
- solutions up ahead...be afraid, be
- very afraid...
-
- pause jsr loop1
- inc looper
- lda looper
- cmp hit
- bne pause
- lda #$00
- sta looper
- rts
-
- loop1 ldx #$fd
- jmp d1
-
- loop2 ldx #$01
- jmp d1
-
- d1 ldy #$ff
- d2 dey
- bne d2
- dex
- bne d1
- rts
-
- "loop1" encompasses "d1", and
- "d2". The whole scheme is a loop
- within a loop, with the idea being to
- be able to get "loop1" to
- approximately equal one beat of the
- music playing in the background.
- After about 30+ (!!!) recompiles, I
- got it almost perfect on an NTSC
- machine. The music plays 17% slower
- on a PAL (european, australian)
- machine and so this demo is
- horribly out of synch in PAL. For
- those of you who are wondering, Mr.
- George Taylor calculated the delay
- loops to be about 2.8% slower on a
- PAL machine when taking into
- consideration the slower PAL CPU and
- the penalties incurred due to "bad
- lines" (when the vic chip steals cpu
- cycles on the bus). As mentioned
- earlier, the "pause" routine
- encompasses everything "loop1" has to
- offer and extends the delay even
- further. The "loop2" routine would
- seem to be useless but it is called
- by the fld-bounce routines. The fld
- takes longer than a regular display
- so I figured I would only need to
- call a delay routine that was a
- fraction of a music "beat" (which is
- what "loop1" tries to be).
-
- Now we get to the real nitty
- gritty of the whole thing. The
- "display" routine and its subsets.
- These make use of the indirect Y
- function which Mensch and company
- thankfully chose to implement in the
- 6502.
-
- But wait, we haven't really gone
- into the indirect Y, have we? Nope,
- because it is tricky to explain.
- Like with movies or sports events,
- you have to be there in order to get
- the feel for it. In general, it is
- an index system that uses a zero page
- pointer of your choice in order to
- jump around to this or that memory
- location. But that's too
- vague...let's really explore it.
-
- Do you recall that at the start
- of the code we defined a few labels
- and basically equated them as memory
- locations? We said that "point = $fb"
- among other things. That is our
- memory (zp) pointer for the Least
- Significant Byte (LSB) and in the
- "display" routine below you will see
- a reference to point+1 which is our
- memory (zero-page) pointer for the
- Most Significant Byte (MSB).
-
- An address in memory is made up
- of two bytes, namely the MSB and
- LSB.
- Think of the MSB as the first two
- digits and the LSB as the last two
- digits, as follows:
-
- $c000 = $c0 MSB + 00 LSB
-
- $00c0 = $00 MSB + c0 LSB
-
- The two together make up a 16-bit
- address and due to how the 6502
- works, it is one reason why 64
- kilobytes can be accessed directly
- (2^16 = 65536).
-
- The indirect Y function allows
- you to set up an MSB and LSB pointer
- in zero page (ie., the first 256
- bytes of memory from $0000 to $00ff).
-
- Note : You can't set a pointer in
- locations $0000, $0001, and $00ff.
- The LSB pointer I chose was $fb and
- by definition, the MSB pointer is
- automatically one memory location
- higher than the LSB pointer, so my
- MSB pointer is at $fc (point + 1).
-
- The "display" routines make use
- of the pointer functions as an index
- to copy C/G picture data to screen
- and color memory. But how does it do
- it, right?
-
- The "viewpic" routine we
- encountered earlier sets the MSB to
- the MSB of the picture that is about
- to be displayed. So for the first
- intro pic at $3000 this would be an
- MSB of #$30. Our LSB was set to zero
- (#$00) at the start of the program.
- So we have an MSB of #$30 and an LSB
- of #$00 = $3000 address. "display"
- now sets the Y register to zero (ldy
- #$00), "pa1" is now ready to copy
- memory.
-
- NOTE : For all the examples
- shown, we will use the MSB of the
- first intro pic
-
- ($3000 = $30 MSB = first two
- digits). The rest of the program
- changes the MSB on the fly so that
- when the "display" routine is
- reached, new pics can be displayed.
- If the MSB didn't change beyond the
- simple incrementations you will see
- below, we'd be stuck with displaying
- one pic.
-
- display ldy #$00 ; "display"
- encompasses all the memory moves that
- follow
-
- ;--------screen data moves----------
-
-
- pa1 lda (point),y ; $x000 $x800
- sta $0400,y
- iny
- bne pa1
-
- As you can see "pa1" takes the
- LSB of the pointer and uses the Y
- register to increment it (with INY)
- and then uses the same increment to
- store values to screen memory (which
- starts at $0400). In long form, this
- routine is just doing this :
-
- LDA $3000 ; take the first byte
- from the stored pic in memory
-
- STA $0400 ; put the first byte to
- the first screen memory location
-
- LDA $3001 ; take the second byte
- from the stored pic in memory
-
- STA $0401 ; put the second byte to
- the second screen memory location
-
- LDA $3002 ; take the third byte
- from the stored pic in memory
-
- STA $0402 ; put the third byte to
- the third screen memory location
-
- The INY instruction can only
- increment 256 times before the LSB
- runs out and it starts looping back
- to zero, so what we do now is
- increment the MSB ! (Remember, the
- BNE instruction checks when Y is
- equal to zero and moves on
- to the next routine -- Also, remember
- that Y itself does not change the
- LSB pointer, it only adds to the LSB
- *value* during the loop. LSB pointer
- itself stays the same, which means we
- can use it in the next routine
- without resetting it - the one we do
- increment is the MSB - via the INC
- instruction).
-
- ldy #$00
- inc point+1
-
- The previous routine "pa1" filled
- the first 256 bytes of screen memory
- with the first 256 bytes of our
- stored pic (i.e., it copied memory
- locations from $3000-$30ff to $0400-
- $04ff). We have just increased our
- MSB by one (using the INC point+1 -
- remember point+1 = our MSB in zero
- page). "pa2" will now do the same
- thing as "pa1" except it is now
- working on the next 256 bytes (i.e.,
- it will copy memory locations from
- $3100-$31ff to $0500-$05ff).
-
- pa2 lda (point),y ; $x100 $x900
- sta $0500,y
- iny
- bne pa2
-
- ldy #$00
- inc point+1
-
- The MSB pointer is incremented
- again... $3200-$32ff to $0600-06ff.
- Please remember we are using the MSB
- of the first pic in this example.
-
- pa3 lda (point),y ; $x200 $xa00
- sta $0600,y
- iny
- bne pa3
-
- ldy #$00
- inc point+1
-
- The MSB pointer is incremented
- again... $3300-$33ff to $0700-$07ff
- ($07e7) Please remember we are using
- the MSB of the first pic in this
- example.
-
- pa4 lda (point),y ; $x300 $xb00
- sta $0700,y
- iny
- bne pa4
-
- ;--------color data moves---------
-
- ldy #$00
- inc point+1
-
- Are we seeing a pattern here? :)
- The MSB keeps getting incremented so
- as to allow yet another 256 byte
- copy-fill to occur. But now things
- change a little since we will now
- copy color memory. Not a problem
- because when we first organized our
- pictures in memory we put color data
- "RIGHT BEHIND" the screen data!!
- Recall, screen data takes up the
- first 1 KB while color data takes up
- the last KB (2 KB total per pic).
- So what do we do? We keep
- incrementing the MSB until the end of
- the pic is reached, but now we
- redirect our copy to the VIC color
- memory area ($d800-$dbff).
-
- "cpa1" copies $3400-$34ff to
- $d800-$d8ff. Please remember we are
- using the MSB of the first pic in
- this example.
-
- cpa1 lda (point),y ; $x400
- $xc00 ; we are now in the second
- kilobyte
-
- sta $d800,y ; of our stored pic
- data in memory.. in other words
-
- iny ; this continual MSB
- incrementation has gone through
-
- bne cpa1 ; the first KB and has
- now hit the second KB where color
- memory for the pictures resides
-
- ldy #$00
- inc point+1 ; increment that MSB
- yet again..
-
- cpa2 lda (point),y ; $x500
- $xd00
- sta $d900,y ; copies $3500-35ff to
- $d900-$d9ff
- iny
- bne cpa2
-
- ldy #$00
- inc point+1 ; increment that MSB
- yet again..
-
- cpa3 lda (point),y ; $x600
- $xe00
- sta $da00,y ; copies $3600-36ff to
- $da00-$daff
- iny
- bne cpa3
-
- ldy #$00
- inc point+1 ; increment that MSB
- for the last time!
-
- cpa4 lda (point),y ; $x700
- $xf00
- sta $db00,y ; copies $3700-$37ff to
- $db00-$dbff ($dbe7)
- iny
- bne cpa4
- rts ; return back to original
- calling routine, whatever
- ; that may be!
-
- ;----------------------------------
-
- nullpic ldy #$00 ; this is
- useless, i never did anything with
- nullpic. I wanted to expand this to
- build some kind of random pic or
- blank screen.. but i forgot about
- it..
-
- ;------fld routine------------------
-
- FLD is known as Flexible Line
- Distancing and the routine that
- follows is an amalgam of something
- The Phantom/FOE did in a Coder's
- World 3 article. I will refer the
- reader to that article and a more
- comprehensive analysis of FLD in C=
- Hacking Issue #7. In brief summary,
- FLD is basically a raster trick that
- bounces the whole screen up and down
- quickly without having to engage in
- moving screen memory or vertically
- scrolling the actual picture data.
- This illustrates a good point about
- coding on the C-64. The best
- "coders" may not necessarily be the
- ones who best know the 6510 CPU.
- Generally, at least in the 'demo
- world', talent is assessed on how
- well the individual knows how to
- properly abuse the ancillary chips
- VIC, SID, CIA, etc.
-
- The FLD technique from my
- standpoint was an exercise in trial
- and error. I sadly did not use a
- sine table to coordinate the bounce-
- effect. I basically sat there
- tweaking it left and right until it
- did what I wanted it to do on my NTSC
- machine. In other words, once I got
- it to bounce the first intro
- pic a few times and gracefully
- depart, I was content. On PAL
- machines the effect is quite skewed
- and is not recommended for young
- viewers in the audience as it is
- rather grotesque :).
-
- fldmain lda #$00
- sta temp2
-
- fld lda #$2a
- cmp $d012
- bne fld
- lda temp2
- cmp #$4f
- beq fldmain2
-
- start ldx temp2
- bounce ldy $d012
- cpy $d012
- dey
- tya
- and #$07
- ora #$10
- sei
- sta $d011
- cli
- dex
- bne bounce
- ldy #$15
- sty $d018
- lda temp2
- clc
- adc #$07
- sta temp2
- jmp fld
-
- fldmain2 lda #$1b ; recovers first
- scn
- sta $d011 ; row from fld trick
- clc
- rts
-
-
- This is it! The end of this
- article and the end of what I hope
- was an enjoyable experience for you.
- Part of the disC=overy project is to
- stave off entropy for as long as
- possible. The best way to do this is
- to convert more order out of chaos in
- our local domain - the world of 64
- :). In effect, by increasing the
- interest and drive we put into these
- old tanks, we shift entropy and chaos
- to the rest of the computer world.
- Because the universe is a closed
- system, this is the best we can do
- and is perhaps a lost cause
- ultimately, but I'll wager no one
- thought we would get this far.
-
- XmikeX
-
-